from docx import Document
from docx.shared import Pt
from docx.enum.text import WD_PARAGRAPH_ALIGNMENT, WD_LINE_SPACING
from docx.oxml.ns import qn


def set_custom_style(paragraph, font_name, font_size, bold=False, italic=False,
                     alignment=None, line_spacing=None, space_before=None, space_after=None):

    """
    word排版的一个脚本，但是不是很好用
    计划书通用排版格式规范（绝对单位：磅）
一、主标题
字体：黑体（加粗）
字号：小二号（18磅）
行距：单倍行距（12磅）
对齐方式：居中对齐
特殊要求：若标题过长需换行，需保持词意完整，行间距适当调整。
二、副标题
字体：楷体（不加粗）
字号：小三号（15磅）
行距：单倍行距（12磅）
对齐方式：居中对齐或右对齐（根据内容层级选择）
特殊要求：若主标题已包含副标题信息，可省略。
三、多级标题
1. 一级标题
字体：黑体（加粗）
字号：三号（16磅）
行距：1.5倍行距（18磅）
对齐方式：左对齐
编号：中文数字（如“一、”）
间距：与正文间空1行（12磅）。
2. 二级标题
字体：仿宋（加粗）
字号：四号（14磅）
行距：1.5倍行距（18磅）
对齐方式：左对齐
编号：中文括号数字（如“（一）”）
间距：与上级标题间空0.5行（6磅）。
3. 三级标题
字体：宋体（加粗）
字号：小四号（12磅）
行距：1.5倍行距（18磅）
对齐方式：左对齐
编号：阿拉伯数字（如“1.”）
间距：与上级标题间不空行。
四、正文
字体：宋体（不加粗）
字号：小四号（12磅）
行距：1.5倍行距（18磅）
对齐方式：两端对齐
特殊要求：
每段首行缩进2字符（约4.2磅）；
段落间不空行，章节间空1行（12磅）；
需强调内容可加粗或倾斜，但需全文统一。
五、其他要素
页边距：上/下2.5厘米，左/右3厘米（A4纸默认值）。
    :param paragraph:
    :param font_name:
    :param font_size:
    :param bold:
    :param italic:
    :param alignment:
    :param line_spacing:
    :param space_before:
    :param space_after:
    :return:
    """
    run = paragraph.runs[0] if paragraph.runs else paragraph.add_run()


    # 设置中文字体（宋体）
    run.font.name = font_name
    run._element.rPr.rFonts.set(qn('w:eastAsia'), font_name)

    # 设置西文字体（使用相同字体名称保持统一）
    run._element.rPr.rFonts.set(qn('w:ascii'), font_name)
    run._element.rPr.rFonts.set(qn('w:hAnsi'), font_name)

    # 其他通用样式设置
    run.font.size = Pt(font_size)
    run.bold = bold
    run.italic = italic

    if alignment:
        paragraph.alignment = alignment

    if line_spacing:
        paragraph.paragraph_format.line_spacing_rule = WD_LINE_SPACING.EXACTLY
        paragraph.paragraph_format.line_spacing = Pt(line_spacing)

    if space_before is not None:
        paragraph.paragraph_format.space_before = Pt(space_before)
    if space_after is not None:
        paragraph.paragraph_format.space_after = Pt(space_after)


def format_document(input_path, output_path):
    doc = Document(input_path)
    new_doc = Document()

    # 统一使用宋体（字号保持原有层级差异）
    base_style = {
        'font_name': '宋体',
        'alignment': WD_PARAGRAPH_ALIGNMENT.JUSTIFY,
        'line_spacing': 18,
        'space_before': 0,
        'space_after': 0
    }

    styles = {
        'main_title': {
            **base_style,
            'font_size': 18,
            'bold': True,
            'alignment': WD_PARAGRAPH_ALIGNMENT.CENTER,
            'space_after': 12
        },
        'sub_title': {
            **base_style,
            'font_size': 15,
            'alignment': WD_PARAGRAPH_ALIGNMENT.CENTER,
            'space_after': 12
        },
        'level1_title': {
            **base_style,
            'font_size': 16,
            'bold': True,
            'alignment': WD_PARAGRAPH_ALIGNMENT.LEFT,
            'space_before': 12,
            'space_after': 12
        },
        'level2_title': {
            **base_style,
            'font_size': 14,
            'bold': True,
            'alignment': WD_PARAGRAPH_ALIGNMENT.LEFT,
            'space_before': 6,
            'space_after': 6
        },
        'level3_title': {
            **base_style,
            'font_size': 12,
            'bold': True,
            'alignment': WD_PARAGRAPH_ALIGNMENT.LEFT,
            'space_after': 0
        },
        'body_text': {
            **base_style,
            'font_size': 12,
            'indent_first_line': Pt(42)
        }
    }

    for paragraph in doc.paragraphs:
        style_name = 'body_text'  # 默认正文样式
        # 根据原始样式判断段落类型（需根据实际文档调整判断逻辑）
        if 'title' in paragraph.style.name.lower():
            if 'main' in paragraph.style.name.lower():
                style_name = 'main_title'
            elif 'sub' in paragraph.style.name.lower():
                style_name = 'sub_title'
            elif 'level1' in paragraph.style.name.lower():
                style_name = 'level1_title'
            elif 'level2' in paragraph.style.name.lower():
                style_name = 'level2_title'
            elif 'level3' in paragraph.style.name.lower():
                style_name = 'level3_title'

        # 获取对应样式配置（排除 indent_first_line）
        current_style = {k: v for k, v in styles[style_name].items() if k != 'indent_first_line'}

        # 创建新段落并应用样式
        new_para = new_doc.add_paragraph()
        set_custom_style(new_para, **current_style)
        new_para.text = paragraph.text

        # 单独处理首行缩进（仅正文需要）
        if style_name == 'body_text' and 'indent_first_line' in styles[style_name]:
            new_para.paragraph_format.first_line_indent = styles[style_name]['indent_first_line']

    new_doc.save(output_path)


# 使用示例
input_path = '排版前文件'
output_path = '排版后文件'
format_document(input_path, output_path)